package com.newasia.shopping.services;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.newasia.shopping.IProductService;
import com.newasia.shopping.constant.GlobalConstants;
import com.newasia.shopping.constants.ShoppingRetCode;
import com.newasia.shopping.converter.ContentConverter;
import com.newasia.shopping.converter.ProductConverter;
import com.newasia.shopping.converter.ProductDectailConverter;
import com.newasia.shopping.converter.SpecOptionConverter;
import com.newasia.shopping.dal.entitys.*;
import com.newasia.shopping.dal.entitys.returnValue.ItemDealerPerm;
import com.newasia.shopping.dal.entitys.returnValue.ItemDetail;
import com.newasia.shopping.dal.entitys.returnValue.ItemFront;
import com.newasia.shopping.dal.entitys.returnValue.ItemSpecOption;
import com.newasia.shopping.dal.persistence.*;
import com.newasia.shopping.dto.*;
import com.newasia.shopping.services.cache.CacheManager;
import com.newasia.shopping.utils.ExceptionProcessorUtils;
import com.newasia.shopping.constant.GlobalConstants;
import com.newasia.shopping.converter.ContentConverter;
import com.newasia.shopping.converter.ProductConverter;
import com.newasia.shopping.converter.ProductDectailConverter;
import com.newasia.shopping.converter.SpecOptionConverter;
import com.newasia.shopping.services.cache.CacheManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 腾讯课堂搜索【咕泡学院】
 * 官网：www.gupaoedu.com
 * 风骚的Mic 老师
 * create-date: 2019/7/24-16:34
 */
@Slf4j
@Service
public class ProductServiceImpl implements IProductService {

    @Autowired
    CacheManager cacheManager;
    @Autowired
    ItemSpuMapper itemSpuMapper;
    @Autowired
    ItemSpecMapper itemSpecMapper;
    @Autowired
    ItemDescMapper itemDescMapper;
    @Autowired
    PanelMapper panelMapper;
    @Autowired
    PanelContentMapper panelContentMapper;
    @Autowired
    ItemSkuPermMapper itemSkuPermMapper;
    @Autowired
    ItemSpecValueMapper itemSpecValueMapper;
    @Autowired
    ItemSkuMapper itemSkuMapper;

    @Autowired
    ProductConverter productConverter;
    @Autowired
    ProductDectailConverter productDectailConverter;
    @Autowired
    ContentConverter contentConverter;
    @Autowired
    SpecOptionConverter specOptionConverter;

    @Override
    public ProductDetailResponse getProductDetail(ProductDetailRequest request) {
        ProductDetailResponse response=new ProductDetailResponse();
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        try{
            request.requestCheck();
            //查询商品缓存
            String json=cacheManager.checkCache(generatorProduceCacheKey(request));
            ProductDetailDto  productDetailDto = new ProductDetailDto();
            if(StringUtils.isNotBlank(json)){
                productDetailDto=JSON.parseObject(json, ProductDetailDto.class);
                cacheManager.expire(generatorProduceCacheKey(request), GlobalConstants.PRODUCT_ITEM_EXPIRE_TIME);
                response.setProductDetailDto(productDetailDto);
            }else{
                ItemDetail itemDetail=itemSpuMapper.selectItemDetailBySkuId(request.getSkuId().longValue());
                if(!request.getMenuId().equals(Long.valueOf(0))){
                    ItemDealerPerm perm = itemSkuPermMapper.selectItemDealerPerm(request.getSkuId(),request.getMenuId());
                    itemDetail.setSkuPrice(perm.getSkuPrice());
                }
                productDetailDto = productDectailConverter.itemDectail2Dto(itemDetail);
                response.setProductDetailDto(productDetailDto);
                //设置缓存
                cacheManager.setCache(generatorProduceCacheKey(request),JSON.toJSON(productDetailDto).toString(),GlobalConstants.PRODUCT_ITEM_EXPIRE_TIME);
            }

            //查询商品属性
            String option =cacheManager.checkCache(generatorProduceSpecKey(productDetailDto.getSpuId()));
            if(StringUtils.isNotBlank(option)){
                List<ItemSpecDto> itemSpecDtos = JSON.parseArray(option, ItemSpecDto.class);
                cacheManager.expire(generatorProduceCacheKey(request),GlobalConstants.PRODUCT_ITEM_EXPIRE_TIME);
                response.setItemSpecDtos(itemSpecDtos);
            }else{
                List<ItemSpecOption> itemSpecOptions = itemSpecMapper.selectItemSpecOptionBySpuId(productDetailDto.getSpuId());
                List<ItemSpecDto> itemSpecDtos = specOptionConverter.itemSpec2Dto(itemSpecOptions);
                int size = 1;
                for (ItemSpecDto dto:itemSpecDtos) {
                    List<Long> ids = dto.getSpecIds();
                    ItemSpecValueExample example = new ItemSpecValueExample();
                    example.createCriteria().andValueIdIn(ids);
                    List<ItemSpecValue> itemSpecValues = itemSpecValueMapper.selectByExample(example);
                    size = size*itemSpecValues.size();
                    itemSpecValues.parallelStream().forEach(itemSpecValue->{
                        Integer num = itemSkuMapper.selectItemSkuNumByValueId(
                                response.getProductDetailDto().getSpuId(),
                                itemSpecValue.getValueId());
                        itemSpecValue.setSize(num);
                    });
                    dto.setItemSpecValueDtos(specOptionConverter.itemSpecValue2Dto(itemSpecValues));
                }
                if(itemSpecDtos.size()==1){
                    size=1;
                }
                for (ItemSpecDto dto:itemSpecDtos) {
                    List<ItemSpecValueDto> values = dto.getItemSpecValueDtos();
                    for (ItemSpecValueDto value:values)
                        if (value.getSize()==0)
                            value.setStatus(0);
                        else
                        if (value.getSize()<(size/values.size())){
                            value.setStatus(1);
                        }else
                            value.setStatus(2);
                }
                response.setItemSpecDtos(itemSpecDtos);
                cacheManager.setCache(generatorProduceSpecKey(productDetailDto.getSpuId()).toString(),JSON.toJSON(itemSpecDtos).toString(),GlobalConstants.PRODUCT_SPEC_EXPIRE_TIME);
            }
        }catch (Exception e){
            log.error("ProductServiceImpl.getProductDetail Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            e.printStackTrace();
        }
        return response;
    }

    /*@Override
    public AllProductResponse getAllProduct(AllProductRequest request) {
        AllProductResponse response=new AllProductResponse();
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        try{
            List<ProductDto> productDtos=new ArrayList<>();
            PageHelper.startPage(request.getPage(),request.getSize());
            String orderCol="created";
            String orderDir="desc";
            if(request.getPriceSort().equals("1")){
                orderCol="price";
                orderDir="asc";
            }else if(request.getPriceSort().equals("-1")){
                orderCol="price";
                orderDir="desc";
            }
            List<ItemFront> items=itemSpuMapper.selectItemFront(request.getCid(),request.getBid(),orderCol,orderDir,request.getPriceGt(),request.getPriceLte());
            PageInfo<ItemFront> pageInfo=new PageInfo<>(items);
            List<ProductDto> productDtosList =productConverter.items2Dto(items);
            response.setProductDtoList(productDtosList);
            response.setTotal(pageInfo.getTotal());
        }catch (Exception e){
            log.error("ProductServiceImpl.getAllProduct Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }*/

    @Override
    public RecommendResponse getRecommendGoods() {
        RecommendResponse response=new RecommendResponse();
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        try{
            String json=cacheManager.checkCache(GlobalConstants.RECOMMEND_PANEL_CACHE_KEY);
            if(StringUtils.isNotBlank(json)){
                List<PanelDto> panelContentItemDtoList = JSON.parseArray(json,PanelDto.class);
                Set<PanelDto> panelDtoSet = new HashSet<>(panelContentItemDtoList);
                response.setPanelContentItemDtos(panelDtoSet);
                return response;
            }
            List<Panel> panels=panelMapper.selectPanelContentById(GlobalConstants.RECOMMEND_PANEL_ID);
            if(panels==null||panels.isEmpty()){
                return response;
            }
            Set<PanelDto> panelContentItemDtos = new HashSet<PanelDto>();
            panels.parallelStream().forEach(panel -> {
                List<PanelContentItem> panelContentItems = panelContentMapper.selectPanelContentAndProductWithPanelId(panel.getId());
                PanelDto panelDto = contentConverter.panen2Dto(panel);
                panelDto.setPanelContentItems(contentConverter.panelContentItemsDto(panelContentItems));
                panelContentItemDtos.add(panelDto);
            });
            response.setPanelContentItemDtos(panelContentItemDtos);
            cacheManager.setCache(GlobalConstants.RECOMMEND_PANEL_CACHE_KEY,JSON.toJSONString(panelContentItemDtos),GlobalConstants.RECOMMEND_CACHE_EXPIRE);

        }catch (Exception e){
            log.error("ProductServiceImpl.getAllProduct Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
        }
        return response;
    }



    @Override
    public GetSkuIdResponse getSkuId(GetSkuIdRequest request) {
        GetSkuIdResponse response = new GetSkuIdResponse();
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        List<Long> options = request.getOptions();
        options.sort(new Comparator<Long>() {
            @Override
            public int compare(Long o1, Long o2) {
                return o1.compareTo(o2);
            }
        });
        try{
            ItemSkuExample example = new ItemSkuExample();
            example.createCriteria().andSkuSpecListIdEqualTo(JSON.toJSONString(options))
                .andSpuIdEqualTo(request.getSpuId()).andStatusEqualTo(1);
            List<ItemSku> itemSkus = itemSkuMapper.selectByExample(example);
            if(itemSkus.size()==0){
                response.setCode(ShoppingRetCode.REQUISITE_ITEM_NOT_EXIST.getCode());
                response.setMsg(ShoppingRetCode.REQUISITE_ITEM_NOT_EXIST.getMessage());
                return response;
            }
            response.setSkuId(itemSkus.get(0).getSkuId());
        }catch (Exception e){
            log.error("ProductServiceImpl.getSkuId Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            e.printStackTrace();
        }
        return response;
    }

    @Override
    public ItemSpecResponse getItemSpecOption(ItemSpecRequest request) {
        ItemSpecResponse response = new ItemSpecResponse();
        response.setCode(ShoppingRetCode.SUCCESS.getCode());
        response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        try {
            request.requestCheck();
            List<ItemSpecOption> itemSpecOptions = itemSpecMapper.selectItemSpecOptionByvalueId(request.getSpuId(),request.getValueIds());
            List<ItemSpecDto> itemSpecDtos = specOptionConverter.itemSpec2Dto(itemSpecOptions);
            int size = 1;

            for (ItemSpecDto dto:itemSpecDtos) {
                List<Long> ids = dto.getSpecIds();
                ItemSpecValueExample example = new ItemSpecValueExample();
                example.createCriteria().andValueIdIn(ids);
                List<ItemSpecValue> itemSpecValues = itemSpecValueMapper.selectByExample(example);
                size = size*itemSpecValues.size();
                for (ItemSpecValue itemSpecValue:itemSpecValues) {
                    List<Long> valueIds = new ArrayList<Long>();
                    for (Long id:request.getValueIds()){
                        valueIds.add(id);
                    }
                    valueIds.add(itemSpecValue.getValueId());
                    valueIds.add(itemSpecValue.getValueId());
                    Integer num = itemSkuMapper.selectItemSkuNumByValueIds(
                            request.getSpuId(),
                            valueIds);
                    itemSpecValue.setSize(num);
                }
                dto.setItemSpecValueDtos(specOptionConverter.itemSpecValue2Dto(itemSpecValues));
            }
            if(itemSpecDtos.size()==1){
                size=1;
            }
            for (ItemSpecDto dto:itemSpecDtos) {
                List<ItemSpecValueDto> values = dto.getItemSpecValueDtos();
                for (ItemSpecValueDto value:values)
                    if (value.getSize()==0)
                        value.setStatus(0);
                    else
                    if (value.getSize()<(size/values.size())){
                        value.setStatus(1);
                    }else
                        value.setStatus(2);
            }
            response.setItemSpecDtos(itemSpecDtos);

        }catch (Exception e){
            log.error("ProductServiceImpl.getSkuId Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            e.printStackTrace();
        }
        return response;
    }

    private String generatorProduceCacheKey(ProductDetailRequest request){
        StringBuilder stringBuilder=new StringBuilder(GlobalConstants.PRODUCT_ITEM_CACHE_KEY);
        stringBuilder.append(":").append(request.getSkuId());
        stringBuilder.append("-").append(request.getMenuId());
        return stringBuilder.toString();
    }

    private String generatorProduceSpecKey(Long spuId){
        StringBuilder stringBuilder=new StringBuilder(GlobalConstants.PRODUCT_ITEM_SPEC_KEY);
        stringBuilder.append(":").append(spuId);
        return stringBuilder.toString();
    }
}
